import { useStorage } from '@vueuse/core';
import { store } from '@/store';
import { usePermissionStoreHook } from '@/store/modules/permission';
import { useDictStoreHook } from '@/store/modules/dict';
import { usePublicInfoStore } from '@/store/modules/public-info';
import { useTagsViewStore } from '@/store/modules/tags-view.js';

import LoginAPI from '@/api/admin/login';

import {
  setToken,
  clearToken,
  setRefresh,
  getRefresh,
  getToken,
} from '@/utils/authToken';

export const useUserStore = defineStore('user', () => {
  const userInfo = useStorage('userInfo', {});

  const permissionStore = usePermissionStoreHook();
  const dictStore = useDictStoreHook();
  const publicInfo = usePublicInfoStore();
  const tagsViewStore = useTagsViewStore();

  /**
   * 登录
   *
   * @param {Object} loginData 登录数据
   * @returns {Promise<void>}
   */
  async function login(loginData) {
    return new Promise(async (resolve, reject) => {
      try {
        const submitData = { ...loginData };
        const { data } = await LoginAPI.login(submitData);
        const { accessToken, refreshToken } = data;
        setToken(accessToken); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
        setRefresh(refreshToken); // 刷新 Token
        await getUserInfo();
        await dictStore.loadDictionaries();
        await permissionStore.generateRoutes();
        resolve();
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 更新 accessToken 和 refreshToken
   * @returns {Promise<void>}
   */
  function refreshToken() {
    return new Promise((resolve, reject) => {
      const refresh_token = getRefresh();
      if (refresh_token) {
        LoginAPI.refreshToken({ refresh_token })
          .then(({ data }) => {
            const { accessToken, refreshToken } = data;
            setToken(accessToken); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
            setRefresh(refreshToken); // 刷新 Token
            resolve(accessToken);
          })
          .catch((error) => {
            reject(error);
          });
      } else {
        reject();
      }
    });
  }

  /**
   * 获取用户信息
   *
   * @returns {Promise<Object>} 用户信息
   */
  function getUserInfo() {
    return new Promise((resolve, reject) => {
      LoginAPI.getUserInfo()
        .then(({ data }) => {
          if (!data) {
            reject('Verification failed, please Login again.');
            return;
          }
          userInfo.value = {};
          Object.assign(userInfo.value, { ...data });
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  /**
   * 登出
   *
   * @returns {Promise<void>}
   */
  function logout() {
    return new Promise((resolve, reject) => {
      LoginAPI.logout()
        .then(() => {
          clearUserSession();
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  /**
   * 清理用户会话
   *
   * @returns {Promise<void>}
   */
  function clearUserSession() {
    return new Promise((resolve) => {
      clearToken();
      permissionStore.resetRouter();
      dictStore.clearDictionaryCache();
      publicInfo.clearPublicInfo();
      tagsViewStore.clearStoredTags();
      resolve();
    });
  }

  return {
    userInfo,
    getUserInfo,
    login,
    refreshToken,
    logout,
    clearUserSession,
  };
});

/**
 * 用于在组件外部（如在 Pinia Store 中）使用 Pinia 提供的 store 实例。
 * 官方文档解释了如何在组件外部使用 Pinia Store：
 * https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component
 */
export function useUserStoreHook() {
  return useUserStore(store);
}
